package com.dominator.serviceImpl;

import com.dominFramework.core.typewrap.Dto;
import com.dominFramework.core.utils.SystemUtils;
import com.dominator.enums.ReqEnums;
import com.dominator.mybatis.dao.*;
import com.dominator.repository.*;
import com.dominator.service.ApiAccountService;
import com.dominator.service.ApiSmsService;
import com.dominator.utils.api.ApiMessage;
import com.dominator.utils.api.ApiMessageUtil;
import com.dominator.utils.api.ApiUtils;
import com.dominator.utils.encode.Des3Utils;
import com.dominator.utils.exception.ApiException;
import com.dominator.utils.wechat.pay.WechatEnterprisePayUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ApiAccountServiceImpl implements ApiAccountService {

    @Autowired
    DaoUser userDao;
    @Autowired
    DaoAccount accountDao;
    @Autowired
    DaoAccountTicket accountTicketDao;
    @Autowired
    DaoAccountRedPacket accountRedPacketDao;
    @Autowired
    ApiSmsService apiSmsService;
    @Autowired
    T_user_bankDao tUserBankDao;
    @Autowired
    T_bankDao tBankDao;


    @Override
    public ApiMessage setPayPassword(Dto dto) throws ApiException {
        ApiUtils.checkParam(dto,"phoneNum,payPassword,verifyCode");
        T_userPO user = userDao.selectByPhoneNum(dto.getString("phoneNum"));
        if (SystemUtils.isEmpty(user)) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        } else if (!"1".equals(user.getIs_valid())) {
            throw new ApiException(ReqEnums.REQ_USER_IS_NOT_VALID);
        }
        T_accountPO account = accountDao.selectByUserId(user.getId());
        if (SystemUtils.isEmpty(account)) {
            accountDao.createAccount(user);
            account = accountDao.selectByUserId(user.getId());
        }
        //验证密码
        // 校验验证码是否存在
        dto.put("verifyType", 4);
        apiSmsService.verifySms(dto);
        account.setPassword(Des3Utils.encode(dto.getString("payPassword")));
        accountDao.updateByPrimaryKey(account);
        return ApiMessageUtil.success();
    }

    @Override
    public ApiMessage recharge(Dto dto) throws ApiException {
        ApiUtils.checkParam(dto, "recharge");
        T_userPO user = userDao.selectByPhoneNum(dto.getString("phoneNum"));
        if (SystemUtils.isEmpty(user)) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        } else if (user.getIs_valid() != "1") {
            throw new ApiException(ReqEnums.REQ_USER_IS_NOT_VALID);
        }
        if (dto.getInteger("recharge") <= 0) {
            throw new ApiException(ReqEnums.ACC_ILLEGAL_AMOUNT);
        }
        //加钱
        T_accountPO account = accountDao.selectByUserId(user.getId());
        account.setMoney(account.getMoney().add(new BigDecimal(dto.getInteger("recharge"))));
        accountDao.updateByPrimaryKey(account);
        return ApiMessageUtil.success();

    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public ApiMessage withdraw(Dto dto) throws ApiException {
        ApiUtils.checkParam(dto,"userBankId,withdraw,phoneNum");
        T_userPO user = userDao.selectByPhoneNum(dto.getString("phoneNum"));
        if (SystemUtils.isEmpty(user)) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        } else if (!"1".equals(user.getIs_valid())) {
            throw new ApiException(ReqEnums.REQ_USER_IS_NOT_VALID);
        }
        if (dto.getInteger("withdraw") <= 0) {
            throw new ApiException(ReqEnums.ACC_ILLEGAL_AMOUNT);
        }
        T_accountPO account = accountDao.selectByUserId(user.getId());
        if (SystemUtils.isEmpty(account)) {
            throw new ApiException(ReqEnums.ACC_NOT_EXSIT);
        }
        if (account.getMoney().compareTo(new BigDecimal(dto.getInteger("withdraw"))) == -1) {
            throw new ApiException(ReqEnums.ACC_LACK_OF_BALANCE);
        }
        //提现
        accountDao.subtract(user.getId(), new BigDecimal(dto.getInteger("withdraw")));
        //手续费计算
        BigDecimal resultMoney =ApiUtils.subPoundage(dto.getBigDecimal("withdraw"));
        //单位转换
        Integer amount=resultMoney.multiply(new BigDecimal(100)).intValue();
        dto.put("amount",amount);
        T_user_bankPO tUserBankPO= tUserBankDao.selectByKey(dto.getString("userBankId"));
        if (SystemUtils.isEmpty(tUserBankPO)){
            throw new ApiException(ReqEnums.BANK_IS_NOT_EXSIT);
        }
        T_bankPO tBankPO=tBankDao.selectByKey(tUserBankPO.getBank_id());

        dto.put("realName",tUserBankPO.getReal_name());
        log.info("--------"+tUserBankPO.getReal_name());
        dto.put("bankNum",tUserBankPO.getBank_num());
        dto.put("bankCode",tBankPO.getBank_code());
        dto.put("desc","用户提现");
        WechatEnterprisePayUtils.PaymentToBankCard(dto);
        return ApiMessageUtil.success();

    }

    @Override
    public ApiMessage redPacket(Dto dto) throws ApiException {
        return ApiMessageUtil.success();
    }

    @Override
    public ApiMessage addPoints(Dto dto) throws ApiException {
        ApiUtils.checkParam(dto,"phoneNum,points");
        T_userPO user = userDao.selectByPhoneNum(dto.getString("phoneNum"));
        if (SystemUtils.isEmpty(user)) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        } else if (!"1".equals(user.getIs_valid())) {
            throw new ApiException(ReqEnums.REQ_USER_IS_NOT_VALID);
        }
        if (dto.getBigDecimal("points").compareTo(BigDecimal.ZERO)<=0){
            throw new ApiException(ReqEnums.ACC_ILLEGAL_POINTS);
        }
        T_accountPO t_accountPO=accountDao.selectByUserId(user.getId());
        t_accountPO.setPoints(t_accountPO.getPoints().add(dto.getBigDecimal("points")));
        accountDao.updateByPrimaryKey(t_accountPO);
        return ApiMessageUtil.success();
    }

    @Override
    public ApiMessage addMoney(Dto dto) throws ApiException {
        ApiUtils.checkParam(dto,"phoneNum,money");
        T_userPO user = userDao.selectByPhoneNum(dto.getString("phoneNum"));
        if (SystemUtils.isEmpty(user)) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        } else if (!"1".equals(user.getIs_valid())) {
            throw new ApiException(ReqEnums.REQ_USER_IS_NOT_VALID);
        }
        if (dto.getBigDecimal("money").compareTo(BigDecimal.ZERO)<=0){
            throw new ApiException(ReqEnums.ACC_ILLEGAL_POINTS);
        }
        T_accountPO t_accountPO=accountDao.selectByUserId(user.getId());
        t_accountPO.setMoney(t_accountPO.getMoney().add(dto.getBigDecimal("money")));
        accountDao.updateByPrimaryKey(t_accountPO);
        return ApiMessageUtil.success();
    }

    @Override
    public ApiMessage getAccount(Dto dto) throws ApiException {
        T_userPO user = userDao.selectByPhoneNum(dto.getString("phoneNum"));
        if (SystemUtils.isEmpty(user)) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        } else if (!"1".equals(user.getIs_valid())) {
            throw new ApiException(ReqEnums.REQ_USER_IS_NOT_VALID);
        }

        T_accountPO account = accountDao.selectByUserId(user.getId());
        if (SystemUtils.isEmpty(account)) {
            accountDao.createAccount(user);
            account = accountDao.selectByUserId(user.getId());
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("points", account.getPoints());
        map.put("money",account.getMoney());
        map.put("isSetPassword",SystemUtils.isNotEmpty(account.getPassword()));
        return ApiMessageUtil.success(map);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public ApiMessage deductPoints(Dto dto) throws ApiException {
        T_userPO user = userDao.selectByPhoneNum(dto.getString("phoneNum"));
        if (SystemUtils.isEmpty(user)) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        } else if (!"1".equals(user.getIs_valid())) {
            throw new ApiException(ReqEnums.REQ_USER_IS_NOT_VALID);
        }
        T_accountPO t_accountPO=accountDao.selectByUserId(user.getId());
        if (SystemUtils.isEmpty(t_accountPO)) {
            accountDao.createAccount(user);
            t_accountPO = accountDao.selectByUserId(user.getId());
        }
        if (t_accountPO.getPoints().subtract(dto.getBigDecimal("points")).compareTo(BigDecimal.ZERO)<0){
            throw new ApiException(ReqEnums.ACC_LACK_OF_POINTS);
        }else {
            t_accountPO.setPoints(t_accountPO.getPoints().subtract(dto.getBigDecimal("points")));
            t_accountPO.setModify_time(new Date());
            accountDao.updateByPrimaryKey(t_accountPO);
        }
        return ApiMessageUtil.success();
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public ApiMessage transferPoints(Dto dto) throws ApiException {
        ApiUtils.checkParam(dto,"phoneNum,toPhoneNum,points");
        deductPoints(dto);
        dto.put("phoneNum",dto.getString("toPhoneNum"));
        addPoints(dto);
        return ApiMessageUtil.success();
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public ApiMessage moneyToPoints(Dto dto) throws ApiException {
        ApiUtils.checkParam(dto,"phoneNum,money");
        T_userPO user = userDao.selectByPhoneNum(dto.getString("phoneNum"));
        if (SystemUtils.isEmpty(user)) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        } else if (!"1".equals(user.getIs_valid())) {
            throw new ApiException(ReqEnums.REQ_USER_IS_NOT_VALID);
        }
        if (dto.getInteger("money") <= 0) {
            throw new ApiException(ReqEnums.ACC_ILLEGAL_AMOUNT);
        }
        T_accountPO account = accountDao.selectByUserId(user.getId());
        if (SystemUtils.isEmpty(account)) {
            throw new ApiException(ReqEnums.ACC_NOT_EXSIT);
        }
        if (account.getMoney().compareTo(new BigDecimal(dto.getInteger("money"))) == -1) {
            throw new ApiException(ReqEnums.ACC_LACK_OF_BALANCE);
        }
        //扣除余额
        accountDao.subtract(user.getId(), new BigDecimal(dto.getInteger("money")));
        //添加积分
        dto.put("points",dto.getInteger("money")*10);
        addPoints(dto);

        return ApiMessageUtil.success();
    }

}
